﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using SpriteAnimator.Classes;
using System.IO;

namespace SpriteAnimator
{
    /// <summary>
    /// Form de gestion d'un sprite
    /// </summary>
    public partial class frmSprite : Form
    {
        #region Variables d'instances

        private int m_iCurrentFrame;
        private float m_fZoomCoef;
        private bool m_bLoopMode;
        private bool m_bSave;
        private Sprite m_oSprite;
        private List<int> m_oFrameToPlay;

        #endregion

        #region Constructeurs

        /// <summary>
        /// Constructeur de la form
        /// </summary>
        /// <param name="p_sTitle">Titre du projet</param>
        public frmSprite(string p_sTitle)
        {
            this.InitializeComponent();

            // *** Initialisation ***

            this.m_bLoopMode = true;
            this.m_oFrameToPlay = new List<int>();
            this.m_iCurrentFrame = -1;
            this.m_fZoomCoef = 1.0f;

            this.m_oSprite = new Sprite();
            this.m_oSprite.Name = p_sTitle;
            this.m_oSprite.BackColor = Color.FromArgb(Convert.ToInt32(Utils.GetRegistryValue("BackColor", Color.CornflowerBlue.ToArgb().ToString(), Utils.REGISTRY_KEY)));

            this.m_bSave = false;

            // *** Mise à jour interface ***

            this.CheckInterface();
            this.CheckIcons();
            this.BuildTitle();
        }

        #endregion

        #region Evénements de l'application

        /// <summary>
        /// Changement de frame
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void cboAnimation_SelectedIndexChanged(object sender, EventArgs e)
        {
            // *** Réinitialisation ***

            this.m_iCurrentFrame = -1;
            this.tmrMain.Enabled = false;
            this.m_oFrameToPlay.Clear();

            // *** Maj interface ***

            this.CheckInterface();

            // *** Maj etat animation ***

            if ( this.cboAnimation.SelectedItem != null )
                this.LoadSequence(this.cboAnimation.SelectedItem as SpriteSequence);

            // *** Rafraichissement ***

            this.picSprite.Invalidate();
        }

        /// <summary>
        /// Click pour gérer les frames
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void cmdFrames_Click(object sender, EventArgs e)
        {
            using ( frmFrames oFrames = new frmFrames(this.m_oSprite.Clone()) )
            {
                this.SetAnimationMode(AnimationMode.Stop);

                if ( oFrames.ShowDialog(this) == DialogResult.Cancel )
                    return;

                // *** Mise à jour des informations ***

                this.ChangeFrames(oFrames.Frames);

                // *** On vérifie l'ensemble ***

                this.VerifySprite();

                // *** Mise à jour graphique ***

                this.PopulateCombo();
                this.CheckInterface();
                this.CheckIcons();

                // *** Modification ***

                this.SetModify(true);
            }
        }

        /// <summary>
        /// Click pour géré la texture
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void cmdTexture_Click(object sender, EventArgs e)
        {
            try
            {
                bool bExist = this.m_oSprite.Texture != null;

                // *** Demande ou est le fichier ***

                this.SetAnimationMode(AnimationMode.Stop);

                using ( frmTexture oFormTexture = new frmTexture(this.m_oSprite.Texture) )
                {
                    // *** Ouverture de la fenêtre ***

                    if ( oFormTexture.ShowDialog(this) == DialogResult.Cancel )
                        return;

                    // *** Charge la texture ***

                    if ( this.m_oSprite.Texture != null )
                    {
                        this.m_oSprite.Texture.Dispose();
                        this.m_oSprite.Texture = null;
                    }

                    this.m_oSprite.Texture = (Image)oFormTexture.Texture.Clone();

                    // *** Demande remise à zéro ***

                    if ( bExist && MessageBox.Show(this, "Voulez-vous réinitialiser les frames et animation du sprite ?", "Changement de texture", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes )
                    {
                        this.m_oSprite.Frames.Clear();
                        this.m_oSprite.Sequences.Clear();

                        this.ClearSequence();
                    }
                }

                // *** Vérification ***

                this.VerifySprite();

                // *** Mise à jour graphique ***

                this.PopulateCombo();
                this.CheckInterface();
                this.CheckIcons();

                // *** Modification ***

                this.SetModify(true);
            }
            catch ( Exception ex )
            {
                frmMain.ShowError(ex);
            }
        }

        /// <summary>
        /// Click pour géré les animations
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void cmdAnimations_Click(object sender, EventArgs e)
        {
            using ( frmAnimation oAnims = new frmAnimation(this.m_oSprite.Clone()) )
            {
                this.SetAnimationMode(AnimationMode.Stop);

                if ( oAnims.ShowDialog(this) == DialogResult.Cancel )
                    return;

                // *** On transfert les animations ***

                this.m_oSprite.Sequences.Clear();

                foreach ( SpriteSequence oSeq in oAnims.Animations )
                {
                    if ( oSeq.FramesIndexes.Count > 0 )
                        this.m_oSprite.Sequences.Add(oSeq.Clone());
                }

                // *** Mise à jour graphique ***

                this.PopulateCombo();
                this.CheckInterface();
                this.CheckIcons();

                // *** Modification ***

                this.SetModify(true);
            }
        }

        /// <summary>
        /// Click play
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void cmdPlay_Click(object sender, EventArgs e)
        {
            if ( this.m_iCurrentFrame > -1 )
                this.tmrMain.Start();

            this.CheckIcons();
        }

        /// <summary>
        /// Click stop
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void cmdStop_Click(object sender, EventArgs e)
        {
            this.tmrMain.Stop();
            this.CheckIcons();
        }

        /// <summary>
        /// Click début
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void cmdDebut_Click(object sender, EventArgs e)
        {
            if ( this.m_iCurrentFrame > -1 )
            {
                this.tmrMain.Stop();
                this.m_iCurrentFrame = 0;
                this.picSprite.Invalidate();
            }

            this.CheckIcons();
        }

        /// <summary>
        /// Click fin
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void cmdFin_Click(object sender, EventArgs e)
        {
            if ( this.m_iCurrentFrame > -1 )
            {
                this.tmrMain.Stop();
                this.m_iCurrentFrame = this.m_oFrameToPlay.Count - 1;
                this.picSprite.Invalidate();
            }

            this.CheckIcons();
        }

        /// <summary>
        /// Click précédent
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void cmdPrecedent_Click(object sender, EventArgs e)
        {
            if ( this.m_iCurrentFrame > -1 )
            {
                this.tmrMain.Stop();
                this.m_iCurrentFrame--;

                if ( this.m_iCurrentFrame < 0 )
                    this.m_iCurrentFrame = this.m_oFrameToPlay.Count - 1;

                this.picSprite.Invalidate();
            }

            this.CheckIcons();
        }

        /// <summary>
        /// Click suivant
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void cmdSuivant_Click(object sender, EventArgs e)
        {
            if ( this.m_iCurrentFrame > -1 )
            {
                this.tmrMain.Stop();
                this.m_iCurrentFrame++;

                if ( this.m_iCurrentFrame > (this.m_oFrameToPlay.Count - 1) )
                    this.m_iCurrentFrame = 0;

                this.picSprite.Invalidate();
            }

            this.CheckIcons();
        }

        /// <summary>
        /// Click sur le mode de loop
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuLoopActif_Click(object sender, EventArgs e)
        {
            this.m_bLoopMode = !this.m_bLoopMode;

            if ( this.m_bLoopMode )
                this.mnuLoop.Image = Properties.Resources.Reload;
            else
                this.mnuLoop.Image = Properties.Resources.Erreur;
        }

        /// <summary>
        /// Click sur le mode de loop
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuColorChange_Click(object sender, EventArgs e)
        {
            this.dlgColor.Color = this.picSprite.BackColor;

            if ( this.dlgColor.ShowDialog(this) == DialogResult.OK )
                this.SetBackground(this.dlgColor.Color);
        }

        /// <summary>
        /// Click sur le mode de loop
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuColorInit_Click(object sender, EventArgs e)
        {
            this.SetBackground(Color.CornflowerBlue);
        }

        /// <summary>
        /// Change le zoom
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuZoom100_Click(object sender, EventArgs e)
        {
            this.PurgeCheck();
            this.m_fZoomCoef = 1.0f;
            this.mnuZoom100.Checked = true;
            this.picSprite.Invalidate();
        }

        /// <summary>
        /// Change le zoom
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuZoom125_Click(object sender, EventArgs e)
        {
            this.PurgeCheck();
            this.m_fZoomCoef = 1.25f;
            this.mnuZoom125.Checked = true;
            this.picSprite.Invalidate();
        }

        /// <summary>
        /// Change le zoom
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuZoom150_Click(object sender, EventArgs e)
        {
            this.PurgeCheck();
            this.m_fZoomCoef = 1.5f;
            this.mnuZoom150.Checked = true;
            this.picSprite.Invalidate();
        }

        /// <summary>
        /// Change le zoom
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuZoom175_Click(object sender, EventArgs e)
        {
            this.PurgeCheck();
            this.m_fZoomCoef = 1.75f;
            this.mnuZoom175.Checked = true;
            this.picSprite.Invalidate();
        }

        /// <summary>
        /// Change le zoom
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuZoom200_Click(object sender, EventArgs e)
        {
            this.PurgeCheck();
            this.m_fZoomCoef = 2.0f;
            this.mnuZoom200.Checked = true;
            this.picSprite.Invalidate();
        }

        /// <summary>
        /// Change le zoom
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuZoom250_Click(object sender, EventArgs e)
        {
            this.PurgeCheck();
            this.m_fZoomCoef = 2.5f;
            this.mnuZoom250.Checked = true;
            this.picSprite.Invalidate();
        }

        /// <summary>
        /// Change le zoom
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void mnuZoom300_Click(object sender, EventArgs e)
        {
            this.PurgeCheck();
            this.m_fZoomCoef = 3.0f;
            this.mnuZoom300.Checked = true;
            this.picSprite.Invalidate();
        }

        /// <summary>
        /// Dessine la picture box
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void picSprite_Paint(object sender, PaintEventArgs e)
        {
            // *** On efface tout ***

            e.Graphics.Clear(this.m_oSprite.BackColor);

            // *** Vérification ***

            if ( this.m_iCurrentFrame > -1 && this.m_oSprite.Texture != null && this.m_oSprite.Frames.Count > 0 )
            {
                // *** Affichage frame ***

                Rectangle oTmp = this.m_oSprite.Frames[this.m_oFrameToPlay[this.m_iCurrentFrame]];

                RectangleF oFrame = new RectangleF(oTmp.X, oTmp.Y, oTmp.Width, oTmp.Height);
                RectangleF oDest = new RectangleF((this.picSprite.Width / 2.0f) - ((oFrame.Width * this.m_fZoomCoef) / 2.0f), (this.picSprite.Height / 2.0f) - ((oFrame.Height * this.m_fZoomCoef) / 2.0f), oFrame.Width * this.m_fZoomCoef, oFrame.Height * this.m_fZoomCoef);

                e.Graphics.DrawImage(this.m_oSprite.Texture, oDest, oFrame, GraphicsUnit.Pixel);

                // *** Affichage numéro grame ***

                using ( SolidBrush oBrush = new SolidBrush(Color.Black) )
                {
                    e.Graphics.DrawString(string.Format("Frame : {0} / {1}", this.m_iCurrentFrame + 1, this.m_oFrameToPlay.Count), this.Font, oBrush, 10.0f, 10.0f);
                }
            }
        }

        /// <summary>
        /// Déclenché lors d'un passage de frame
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void tmrMain_Tick(object sender, EventArgs e)
        {
            this.m_iCurrentFrame++;

            if ( this.m_iCurrentFrame > (this.m_oFrameToPlay.Count - 1) )
            {
                if ( this.m_bLoopMode )
                    this.m_iCurrentFrame = 0;
                else
                {
                    this.m_iCurrentFrame = this.m_oFrameToPlay.Count - 1;
                    this.tmrMain.Stop();
                    this.CheckIcons();
                }
            }

            this.picSprite.Invalidate();
        }

        /// <summary>
        /// Lors du changement de text
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void txtInterval_TextChanged(object sender, EventArgs e)
        {
            int iTime = 30;

            if ( !int.TryParse(this.txtInterval.Text, out iTime) )
                this.txtInterval.Text = this.tmrMain.Interval.ToString();
            else
                this.tmrMain.Interval = int.Parse(this.txtInterval.Text);
        }

        /// <summary>
        /// Se produit sur la fermeture de la fenêtre
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void frmSprite_FormClosing(object sender, FormClosingEventArgs e)
        {
            if ( this.m_bSave )
            {
                DialogResult oTmp = MessageBox.Show(this, "Des modifications ont été apporté, voulez-vous les enregistrer ?", "Sprite", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Information);

                if ( oTmp == DialogResult.Cancel )
                    e.Cancel = true;
                else if ( oTmp == DialogResult.Yes )
                    this.Save(false);
            }
        }

        /// <summary>
        /// Se produit sur le changement de taille de la fenêtre
        /// </summary>
        /// <param name="sender">Source de l'appel</param>
        /// <param name="e">Argument de l'appel</param>
        private void frmSprite_Resize(object sender, EventArgs e)
        {
            this.picSprite.Invalidate();
        }

        #endregion

        #region Fonctions privées

        /// <summary>
        /// Défini le titre de la fenêtre
        /// </summary>
        private void BuildTitle()
        {
            this.Text = String.Format("Sprite - {0} {1}", this.m_oSprite.Name, this.m_bSave ? "(Modifié)" : String.Empty);
        }

        /// <summary>
        /// Change la liste des frames
        /// </summary>
        /// <param name="p_oList">Liste ordonnée des nouvelles frames</param>
        private void ChangeFrames(List<Rectangle> p_oList)
        {
            // *** On vide la liste ***

            this.m_oSprite.Frames.Clear();

            // *** On affecte la nouvelle ***

            foreach ( Rectangle oRect in p_oList )
                this.m_oSprite.Frames.Add(oRect);
        }

        /// <summary>
        /// Remet à jour les icones
        /// </summary>
        private void CheckIcons()
        {
            this.cmdStop.Image = Properties.Resources.Stop;
            this.cmdPlay.Image = Properties.Resources.Play;

            if ( this.tmrMain.Enabled )
                this.cmdPlay.Image = Properties.Resources.PlayPush;
            else
                this.cmdStop.Image = Properties.Resources.StopPush;
        }

        /// <summary>
        /// Active les boutons en fonction de ce qui est renseigné
        /// </summary>
        private void CheckInterface()
        {
            bool bTexture = this.m_oSprite.Texture != null;
            bool bFrame = this.m_oSprite.Frames.Count > 0;
            bool bAnimation = this.m_oSprite.Sequences.Count > 0;
            bool bSelection = this.cboAnimation.SelectedItem != null;

            // *** Affectation des états ***

            this.lblSequence.Enabled = bTexture && bFrame && bAnimation;
            this.cboAnimation.Enabled = bTexture && bFrame && bAnimation;

            this.lblInterval.Enabled = bTexture && bFrame && bAnimation && bSelection;
            this.txtInterval.Enabled = bTexture && bFrame && bAnimation && bSelection;

            this.cmdDebut.Enabled = bTexture && bFrame && bAnimation && bSelection;
            this.cmdPrecedent.Enabled = bTexture && bFrame && bAnimation && bSelection;
            this.cmdStop.Enabled = bTexture && bFrame && bAnimation && bSelection;
            this.cmdPlay.Enabled = bTexture && bFrame && bAnimation && bSelection;
            this.cmdSuivant.Enabled = bTexture && bFrame && bAnimation && bSelection;
            this.cmdFin.Enabled = bTexture && bFrame && bAnimation && bSelection;

            this.cmdFrames.Enabled = bTexture;
            this.cmdAnimations.Enabled = bTexture && bFrame;
        }

        /// <summary>
        /// Efface la zone de sprite
        /// </summary>
        private void ClearSequence()
        {
            this.m_iCurrentFrame = -1;
            this.m_oFrameToPlay.Clear();
            this.picSprite.Invalidate();
        }

        /// <summary>
        /// Charge une séquence
        /// </summary>
        /// <param name="p_oSequence">Définition de la séquence</param>
        private void LoadSequence(SpriteSequence p_oSequence)
        {
            // *** Initialisation ***

            this.m_iCurrentFrame = 0;
            this.m_oFrameToPlay.Clear();

            // *** Création des frames ***

            if ( p_oSequence.Type == SpriteAnimationType.Range )
            {
                for ( int i = p_oSequence.FramesIndexes[0]; i <= p_oSequence.FramesIndexes[1]; i++ )
                    this.m_oFrameToPlay.Add(i);
            }
            else
            {
                foreach ( int iFrame in p_oSequence.FramesIndexes )
                    this.m_oFrameToPlay.Add(iFrame);
            }
        }

        /// <summary>
        /// Charge les séquences dans la combo
        /// </summary>
        private void PopulateCombo()
        {
            // *** On la vide ***

            this.cboAnimation.Items.Clear();

            // *** On la remplis ***

            this.cboAnimation.Sorted = false;

            foreach ( SpriteSequence oSeq in this.m_oSprite.Sequences )
                this.cboAnimation.Items.Add(oSeq);

            this.cboAnimation.Sorted = true;

            // *** Sélection du premier ***

            if ( this.cboAnimation.Items.Count > 0 )
                this.cboAnimation.SelectedIndex = 0;
        }

        /// <summary>
        /// Retire les checkbox du menu zomm
        /// </summary>
        private void PurgeCheck()
        {
            this.mnuZoom100.Checked = false;
            this.mnuZoom125.Checked = false;
            this.mnuZoom150.Checked = false;
            this.mnuZoom175.Checked = false;
            this.mnuZoom200.Checked = false;
            this.mnuZoom250.Checked = false;
            this.mnuZoom300.Checked = false;
        }

        /// <summary>
        /// Modifie le statut de modification
        /// </summary>
        /// <param name="p_bMode">TRUE modifié, FALSE sinon</param>
        private void SetModify(bool p_bMode)
        {
            this.m_bSave = p_bMode;
            this.BuildTitle();
        }

        /// <summary>
        /// Vérifie l'intégrité du sprite
        /// </summary>
        private void VerifySprite()
        {
            bool bErreurs = false;

            // *** Vérification des frames ***

            for ( int i = 0; i < this.m_oSprite.Frames.Count; i++ )
            {
                Rectangle oFrame = this.m_oSprite.Frames[i];

                if ( (oFrame.X + oFrame.Width) > this.m_oSprite.Texture.Width )
                {
                    this.m_oSprite.Frames.RemoveAt(i);
                    bErreurs = true;
                    i--;
                }
                else if ( (oFrame.Y + oFrame.Height) > this.m_oSprite.Texture.Height )
                {
                    this.m_oSprite.Frames.RemoveAt(i);
                    bErreurs = true;
                    i--;
                }
            }

            // *** Vérification des animations ***

            for ( int i = 0; i < this.m_oSprite.Sequences.Count; i++ )
            {
                if ( bErreurs )
                    break;

                SpriteSequence oSeq = this.m_oSprite.Sequences[i];

                if ( oSeq.Type == SpriteAnimationType.List )
                {
                    for ( int j = 0; j < oSeq.FramesIndexes.Count; j++ )
                    {
                        if ( oSeq.FramesIndexes[j] >= this.m_oSprite.Frames.Count )
                        {
                            bErreurs = true;
                            break;
                        }
                    }
                }
                else if ( oSeq.Type == SpriteAnimationType.Range )
                {
                    if ( this.m_oSprite.Frames.Count != 2 || oSeq.FramesIndexes[0] >= oSeq.FramesIndexes[1] || oSeq.FramesIndexes[1] >= this.m_oSprite.Frames.Count )
                    {
                        bErreurs = true;
                        break;
                    }
                }
            }

            // *** Signalement des erreurs ***

            if ( bErreurs )
            {
                this.m_oSprite.Sequences.Clear();
                this.ClearSequence();

                MessageBox.Show(this, "Certaines données n'étant plus cohérantes, toutes les animations ont été supprimée.", "Vérification", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        #endregion

        #region Fonctions publiques

        /// <summary>
        /// Charge une définitin de sprite déjà existante
        /// </summary>
        /// <param name="p_sPath">Chemin de la définition</param>
        public void LoadSprite(string p_sPath)
        {
            // *** Chargement ***

            this.m_oSprite.Load(p_sPath);

            // *** Mise à jour interface ***

            this.BuildTitle();
            this.picSprite.BackColor = this.m_oSprite.BackColor;

            this.CheckInterface();
            this.PopulateCombo();
        }

        /// <summary>
        /// Sauvegarde le sprite en cours
        /// </summary>
        /// <param name="p_bShowLocation">TRUE force de précisé le chemin</param>
        public void Save(bool p_bShowLocation)
        {
            string sPath;
            string sName;

            // *** Vérification ***

            if ( this.m_oSprite.Texture == null )
            {
                MessageBox.Show(this, "Vous devez au moins spécifier une texture pour pouvoir enregistrer.", "Sprite", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            try
            {
                // *** Demande de chemin ***

                if ( p_bShowLocation || String.IsNullOrEmpty(this.m_oSprite.FilePath) )
                {
                    this.dlgSave.FileName = this.m_oSprite.FilePath;

                    if ( String.IsNullOrEmpty(this.dlgSave.FileName) )
                        this.dlgSave.FileName = this.m_oSprite.Name;

                    if ( this.dlgSave.ShowDialog(this) == DialogResult.Cancel )
                        return;

                    sPath = Path.GetDirectoryName(this.dlgSave.FileName);
                    sName = Path.GetFileNameWithoutExtension(this.dlgSave.FileName);
                }
                else
                {
                    sPath = Path.GetDirectoryName(this.m_oSprite.FilePath);
                    sName = Path.GetFileNameWithoutExtension(this.m_oSprite.FilePath);
                }

                // *** Enregistrement ***

                this.m_oSprite.Save(sPath, sName);
                this.SetModify(false);
            }
            catch ( Exception e )
            {
                MessageBox.Show(this, String.Format("Un erreur est survenue pendant l'enregistrement.\n\n{0}", e.Message), "Sprite", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Affecte l'animation en cours
        /// </summary>
        /// <param name="p_eMode"></param>
        public void SetAnimationMode(AnimationMode p_eMode)
        {
            switch ( p_eMode )
            {
                case (AnimationMode.Begin):
                    this.cmdDebut_Click(null, null);
                    break;

                case (AnimationMode.Previous):
                    this.cmdPrecedent_Click(null, null);
                    break;

                case (AnimationMode.Stop):
                    this.cmdStop_Click(null, null);
                    break;

                case (AnimationMode.Play):
                    this.cmdPlay_Click(null, null);
                    break;

                case (AnimationMode.Next):
                    this.cmdSuivant_Click(null, null);
                    break;

                case (AnimationMode.End):
                    this.cmdFin_Click(null, null);
                    break;
            }
        }

        /// <summary>
        /// Affecte la couleur de fond
        /// </summary>
        /// <param name="p_oColor">Couleur de fond</param>
        public void SetBackground(Color p_oColor)
        {
            this.picSprite.BackColor = p_oColor;
            this.m_oSprite.BackColor = p_oColor;

            // *** Modification ***

            this.SetModify(true);
        }

        /// <summary>
        /// Affecte le mode loop
        /// </summary>
        /// <param name="p_bLoop"></param>
        public void SetLoop(bool p_bLoop)
        {
            this.m_bLoopMode = !p_bLoop;
            this.mnuLoopActif_Click(null, null);
        }

        /// <summary>
        /// Met à jour le zoom
        /// </summary>
        /// <param name="p_eZoom">Type de zoom</param>
        public void SetZoom(ZoomMode p_eZoom)
        {
            switch ( p_eZoom )
            {
                case (ZoomMode.Zoom100):
                    this.mnuZoom100_Click(null, null);
                    break;

                case (ZoomMode.Zoom125):
                    this.mnuZoom125_Click(null, null);
                    break;

                case (ZoomMode.Zoom150):
                    this.mnuZoom150_Click(null, null);
                    break;

                case (ZoomMode.Zoom175):
                    this.mnuZoom175_Click(null, null);
                    break;

                case (ZoomMode.Zoom200):
                    this.mnuZoom200_Click(null, null);
                    break;

                case (ZoomMode.Zoom250):
                    this.mnuZoom250_Click(null, null);
                    break;

                case (ZoomMode.Zoom300):
                    this.mnuZoom300_Click(null, null);
                    break;

            }
        }

        /// <summary>
        /// Affiche la zone animation
        /// </summary>
        public void ShowAnimation()
        {
            if ( this.cmdAnimations.Enabled )
                this.cmdAnimations_Click(this.cmdAnimations, EventArgs.Empty);
            else
                MessageBox.Show(this, "Vous ne pouvez pas ouvrir la fenêtre des animations.", "Sprite", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        /// <summary>
        /// Affiche la zone frames
        /// </summary>
        public void ShowFrames()
        {
            if ( this.cmdFrames.Enabled )
                this.cmdFrames_Click(this.cmdFrames, EventArgs.Empty);
            else
                MessageBox.Show(this, "Vous ne pouvez pas ouvrir la fenêtre des frames.", "Sprite", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        /// <summary>
        /// Affiche la zone texture
        /// </summary>
        public void ShowTexture()
        {
            this.cmdTexture_Click(this.cmdTexture, EventArgs.Empty);
        }

        #endregion
    }
}
